package uk.ac.glasgow.demosocs.impl.ui;

import uk.ac.glasgow.clui.CommandDescription;

import uk.ac.glasgow.clui.ArgumentsDescription;
import uk.ac.glasgow.clui.MinimumArguments;
import uk.ac.glasgow.clui.SystemCommand;
import uk.ac.glasgow.clui.SystemCommandException;
import uk.ac.glasgow.demosocs.Election;
import uk.ac.glasgow.demosocs.Vote;
import uk.ac.glasgow.demosocs.VotingSystem;
import uk.ac.glasgow.demosocs.impl.AltVote;
import uk.ac.glasgow.demosocs.impl.AlternativeVote;
import uk.ac.glasgow.demosocs.impl.OneOfNVoteStub;
import uk.ac.glasgow.demosocs.impl.Referendum;

@MinimumArguments(1)
@CommandDescription("Cast a vote in the currently selected election for the specified candidate.")
@ArgumentsDescription("<candidate>")
public class CastVoteCommand extends SystemCommand<VotingSystem> {

	public CastVoteCommand(VotingSystem facade) {
		super(facade);
	}

	@Override
	public String processCommand(String[] arguments)
			throws SystemCommandException {

		Election election = facade.getCurrentElection();

		if (election == null)
			throw new SystemCommandException("No current election set.");

		String guid = facade.getCurrentUserGUID();
		
		if (guid == null)
			throw new SystemCommandException("No current user set.");

		if (election.getClass() == Election.class) {
			String candidate = arguments[0];

			facade.castVote(new OneOfNVoteStub(candidate));

			return "A vote was cast for [" + candidate + "].";
		}
		else if (election.getClass() == Referendum.class) {
			return null;
		}
		else {
			//dealing with an alt vote
			AlternativeVote altElection = (AlternativeVote) election;
			//check the right number of choices are enetered
			if (arguments.length != altElection.getNumberOfChoices() * 2){
				return "You must cast all of your available preferences. In this case = " + altElection.getNumberOfChoices();
			}
			//check that all the odd numbers can be cast to Ints
			for (int i = 1; i < altElection.getNumberOfChoices() * 2; i += 2){
				int preference;
				try {
				    preference = Integer.parseInt(arguments[i]);
				    // Yes!  An integer.
				} catch (NumberFormatException nfe) {
				    return "Invalid arguments for cast an alternative vote, structure =\n" +
				    		"<GUID> <preference> <GUID> <preference> <GUID> <preference>......";
				}
				
				if (preference < 0 || preference > altElection.getNumberOfChoices()){
					return "Invalid preference number, should be between 0 and " + altElection.getNumberOfChoices();
				}
				AltVote vote = new AltVote(arguments[i-1], preference);
				facade.castVote(vote);
				System.out.println("Vote cast"); 
			}
			
			return "";
			
			
		}
		//System.out.println("Error casting vote");
		//return null;
		
		
	}
}
